package com.zhangmeng.online.exam.controller;

import com.alibaba.fastjson2.JSONArray;
import com.zhangmeng.online.exam.dao.ExamDao;
import com.zhangmeng.online.exam.dao.PaperDao;
import com.zhangmeng.online.exam.dao.UserDao;
import com.zhangmeng.online.exam.dto.Result;
import com.zhangmeng.online.exam.entity.*;
import com.zhangmeng.online.exam.service.ExamService;
import com.zhangmeng.online.exam.utils.UserUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.zhangmeng.online.exam.utils.PageUtils.getPageNum;

/**
 * @author zm
 * @date 2025/4/17 16:24
 * @version: 1.0
 */
@RestController
@RequestMapping("/exam")
public class ExamController {

    @Autowired
    private ExamDao examDao;

    @Autowired
    private PaperDao paperDao;

    @Autowired
    private UserDao userDao;

    @Autowired
    private ExamService examService;

    @RequestMapping("/user/list")
    public Result userList(String paperId, Integer pageNum, Integer pageSize) {

        List<Exam> exams = this.getExamByPaperId(Long.parseLong(paperId));
        List<User> users = new ArrayList<>();

        if (!exams.isEmpty()) {
            for (Exam exam : exams) {
                users.add(exam.getUser());
            }
        }

        Specification<User> specification = (root, query, criteriaBuilder) -> {

            List<Predicate> predicates = new ArrayList<>();
            predicates.add(criteriaBuilder.equal(root.get("status"), User.Status.VALID));

            // 条件2：用户必须拥有学生角色
            Join<User, Role> roleJoin = root.join("roles"); // 关联用户和角色表
            predicates.add(criteriaBuilder.equal(roleJoin.get("type"), Role.Type.STUDENT));

            // 条件3：用户不能是已经参加过该试卷的学生
            if (!users.isEmpty()) {
                predicates.add(criteriaBuilder.not(root.get("id").in(users.stream().map(User::getId).toList())));
            }


            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        };

        Pageable pageable = PageRequest.of(getPageNum(pageNum), pageSize);
        Page<User> all = userDao.findAll(specification, pageable);
        List<Map<String, Object>> resultList = new ArrayList<>();
        for (User user : all.getContent()) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", user.getId());
            map.put("username", user.getUsername());
            map.put("email", user.getEmail());
            map.put("phone", user.getPhone());
            map.put("type", user.getRoles().stream().toList().get(0).getType().getDesc());
            resultList.add(map);
        }

        // 处理查询结果并返回
        return Result.success(pageNum, pageSize, all.getTotalElements(), resultList);
    }

    @RequestMapping("/user/choose/list")
    public Result userChooseList(String paperId, Integer pageNum, Integer pageSize) {

        List<Exam> exams = this.getExamByPaperId(Long.parseLong(paperId));
        List<User> users = new ArrayList<>();

        if (!exams.isEmpty()) {
            for (Exam exam : exams) {
                users.add(exam.getUser());
            }
        }

        Specification<User> specification = (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (!users.isEmpty()) {
                predicates.add(criteriaBuilder.in(root.get("id")).value(users.stream().map(User::getId).toList()));
                predicates.add(criteriaBuilder.equal(root.get("status"), User.Status.VALID));
            } else {
                // 添加一个无效条件，确保查询结果为空
                predicates.add(criteriaBuilder.equal(root.get("id"), -1));
            }
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        };

        Pageable pageable = PageRequest.of(getPageNum(pageNum), pageSize);
        Page<User> all = userDao.findAll(specification, pageable);
        List<Map<String, Object>> resultList = new ArrayList<>();
        for (User user : all.getContent()) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", user.getId());
            map.put("username", user.getUsername());
            map.put("email", user.getEmail());
            map.put("phone", user.getPhone());
            map.put("type", user.getRoles().stream().toList().get(0).getType().getDesc());
            resultList.add(map);
        }

        // 处理查询结果并返回
        return Result.success(pageNum, pageSize, all.getTotalElements(), resultList);
    }

    private List<Exam> getExamByPaperId(Long paperId) {
        Specification<Exam> specification = (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();

            if (paperId != null) {
                predicates.add(criteriaBuilder.equal(root.get("paper").get("id"), paperId));
            }
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        };
        List<Exam> all = examDao.findAll(specification);
        return all;
    }


    @RequestMapping("/list")
    public Result list(Integer pageNum, Integer pageSize) {
        Pageable pageable = PageRequest.of(getPageNum(pageNum), pageSize);
        Specification<Exam> specification = (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            Long userId = UserUtils.getCurrentUserId();
            if (userId != null) {
                predicates.add(criteriaBuilder.equal(root.get("user").get("id"), userId));
            }
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        };


        Page<Exam> all = examDao.findAll(pageable);
        List<Map<String, Object>> resultList = new ArrayList<>();

        for (Exam exam : all.getContent()) {
            Map<String, Object> map = new HashMap<>();

            Paper paper = exam.getPaper();

            map.put("id", exam.getId());
            map.put("paperName", paper.getName());
            map.put("paperId", paper.getId());
            map.put("examTime", paper.getExamTime());
            map.put("subjectName", paper.getSubject().getName());
            map.put("score", paper.getTotalScore());
            map.put("status", exam.getStatus() == null ? "" : exam.getStatus().getDesc());

            resultList.add(map);
        }

        // 处理查询结果并返回
        return Result.success(pageNum, pageSize, all.getTotalElements(), resultList);
    }

    @RequestMapping("/choosePaper/save")
    public Result choosePaperSave(@RequestParam @RequestBody Map<String, Object> params) {

        String id = (String) params.get("id");
        Paper paper = this.paperDao.getById(Long.parseLong(id));
        String ids = (String) params.get("ids");

        if (ids != null && !ids.isEmpty()) {
            List<String> idArr = JSONArray.parseArray(ids, String.class);
            for (String userId : idArr) {
                User user = userDao.getById(Long.parseLong(userId));
                Exam exam = this.getExamByPaperIdAndUserId(paper.getId(), user.getId());
                if (exam == null) {
                    exam = new Exam();
                    exam.setPaper(paper);
                    exam.setUser(user);
                    examDao.save(exam);
                }
            }
        }

        return Result.success(null);
    }

    private Exam getExamByPaperIdAndUserId(Long paperId, Long userId) {

        Specification<Exam> specification = (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (userId != null) {
                predicates.add(criteriaBuilder.equal(root.get("user").get("id"), userId));
            }
            if (paperId != null) {
                predicates.add(criteriaBuilder.equal(root.get("paper").get("id"), paperId));
            }
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        };
        List<Exam> all = examDao.findAll(specification);
        if (all.isEmpty()) {
            return null;
        }
        return all.get(0);
    }


    @RequestMapping("/saveAnswer")
    public Result saveAnswer(@RequestParam @RequestBody Map<String, Object> params) {

        String jsonData = params.get("json_data").toString();

        try {
            List<Map> maps = JSONArray.parseArray(jsonData, Map.class);
            // 如果解析成功，继续处理 maps
            for (Map map : maps) {
                this.examService.saveAnswer(map);
            }

        } catch (com.alibaba.fastjson2.JSONException e) {
            // 处理 jsonData 格式不正确的情况
            return Result.error("jsonData 格式不正确，请提供有效的 JSON 数据。");
        } catch (Exception e) {
            // 处理其他未知错误的情况
            return Result.error("发生未知错误，请联系系统管理员。");
        }



        return Result.success(null);
    }



}
